package com.bootlever.framework.redis.configuration;

import com.bootlever.framework.common.utils.StringUtils;
import com.bootlever.framework.redis.cfg.BootLeverJedisPoolConfig;
import com.bootlever.framework.redis.properties.RedisProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.*;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@Configuration
public class JedisConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(JedisConfiguration.class);

    @Autowired
    private RedisProperties redisProperties;

    /**
     * 单机版
     * @return
     */
    @Bean
    @ConditionalOnExpression("'${bootlever.framework.redis.jedis.autoconfiguration:true}'=='true'" +
            "&&'${bootlever.framework.redis.type:singleton}'=='singleton'")
    @ConditionalOnMissingBean(JedisPool.class)
    public JedisPool jedisPool(){
        logger.info("开始初始化JedisPool");
        if (redisProperties == null || redisProperties.getJedis() == null) {
            logger.info("参数redisProperties为null 或config为null，停止初始化");
            return null;
        }
        BootLeverJedisPoolConfig config = redisProperties.getJedis();
        String[] hostAndPort = redisProperties.getAddress().split(":");
        JedisPool jedisPool = new JedisPool(config.getPool(),hostAndPort[0],Integer.parseInt(hostAndPort[1]),redisProperties.getTimeout(),
                redisProperties.getPassword(),redisProperties.getDatabase(),redisProperties.getClientName());
        logger.info("初始化JedisPool结束");
        return  jedisPool;
    }

    /**
     * 哨兵模式
     * @return
     */
    @Bean
    @ConditionalOnExpression("'${bootlever.framework.redis.type:singleton}'=='sentinel'&&" +
            "'${bootlever.framework.redis.jedis.autoconfiguration:true}'=='true'")
    @ConditionalOnMissingBean(JedisSentinelPool.class)
    public JedisSentinelPool jedisSentinelPool() {
        logger.info("开始初始化JedisSentinePool");
        if (redisProperties == null || redisProperties.getJedis() == null) {
            logger.info("参数redisProperties为null 或config为null，停止初始化");
            return null;
        }
        BootLeverJedisPoolConfig config = redisProperties.getJedis();
        BootLeverJedisPoolConfig.Sentinel sentinel = config.getSentinel();
        if (sentinel == null) {
            logger.info("参数sentinel为null停止初始化");
            return null;
        }
        //Set<String> 格式 ip:port,ip:port,ip:port
        Set<String> set = new HashSet<String>();
        Collections.addAll(set, redisProperties.getNodes().split(","));
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(redisProperties.getMaster(), set,config.getPool(),
            redisProperties.getTimeout(),redisProperties.getPassword(),redisProperties.getDatabase(), redisProperties.getClientName());
        logger.info("初始化JedisSentinelPool结束");
        return jedisSentinelPool;
    }

    /**
     * 集群
     * @return
     */
    @Bean
    @ConditionalOnExpression("'${bootlever.framework.redis.type:singleton}'=='cluster'&&" +
            "'${bootlever.framework.redis.jedis.autoconfiguration:true}'=='true'")
    @ConditionalOnMissingBean(JedisCluster.class)
    public JedisCluster jedisCluster() {
        logger.info("开始初始化JedisCluster");
        if (redisProperties == null || redisProperties.getJedis() == null) {
            logger.info("参数redisProperties为null或者config为null，停止初始化");
            return null;
        }
        BootLeverJedisPoolConfig config = redisProperties.getJedis();
        BootLeverJedisPoolConfig.Cluster cluster = config.getCluster();
        if (cluster == null) {
            logger.info("参数Cluster为null,停止初始化");
            return null;
        }
        //格式ip:port,ip:port
        Set<HostAndPort> hostAndPorts = new HashSet<HostAndPort>();
        for (String host : redisProperties.getNodes().split(",")){
            String[] arr = host.split(":");
            HostAndPort hostAndPort = new HostAndPort(arr[0],Integer.parseInt(arr[1]));
            hostAndPorts.add(hostAndPort);
        }
        JedisCluster jedisCluster = null;
        if (StringUtils.isBlank(redisProperties.getPassword())) {
            jedisCluster = new JedisCluster(hostAndPorts,cluster.getConnectionTimeout(),cluster.getSoTimeout(),
                    cluster.getMaxAttempts(),config.getPool());
        } else {
            jedisCluster = new JedisCluster(hostAndPorts,cluster.getConnectionTimeout(),cluster.getSoTimeout(),
                    cluster.getMaxAttempts(), redisProperties.getPassword(),config.getPool());
        }
        logger.info("初始化JedisCluster结束");
        return jedisCluster;
    }
}
